import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:jverify/jverify.dart';
import 'package:zrjz/comm/constants/api_constants.dart';
import 'package:zrjz/comm/constants/app_constant.dart';
import 'package:zrjz/comm/constants/color_constants.dart';
import 'package:zrjz/comm/utils/device_utils.dart';
import 'package:zrjz/comm/utils/log_utils.dart';

typedef TokenCallback = void Function(String token, String loginToken);

class JVerifyService extends GetxService {
  static JVerifyService get to => Get.find();

  //秒验
  // 统一 key
  final String f_result_key = "result";

  // 错误码
  final String f_code_key = "code";

  // 回调的提示信息
  final String f_msg_key = "message";

  // 运营商信息
  final String f_opr_key = "operator";

  //秒验对象，判断是否为空
  Jverify? _jverify;

  // 是否已经预取号了，不要重复预取号
  final Completer<bool> _isPreLoginedCompleter = Completer<bool>();

  //是否已经完成初始化
  final Completer<bool> _initCompleter = Completer<bool>();

  //回调详情数据
  TokenCallback? mTokenCallback;

  /// 初始化JVerify秒验，并设置一些监听
  Future<void> _initJVerify() async {
    Log.d("准备初始化JVerify");
    _jverify = Jverify();

    // 初始化 SDK 之前添加监听
    _jverify?.addSDKSetupCallBackListener((JVSDKSetupEvent event) {
      Log.d("receive sdk setup call back event :${event.toMap()}");
      //根据 Code 判断是否真正的初始化成功了
      int code = event.toMap()[f_code_key];
      if (code == 8000) {
        _initCompleter.complete(true);
      }
    });

    // 是否打开调试模式
    _jverify?.setDebugMode(!AppConstant.inProduction);
    // 初始化sdk, appKey 和 channel 只对ios设置有效
    _jverify?.setup(appKey: "23dedb30175208f894d3756f", channel: "devloper-default");

    //授权页面点击事件监听
    _jverify?.addAuthPageEventListener((JVAuthPageEvent event) {
      Log.d("receive auth page event :${event.toMap()}");
    });
  }

  /// 一键登录的预取号
  Future<void> preLogin() async {
    if (_jverify == null) {
      await _initJVerify();

      bool isInitialized = await _initCompleter.future;
      if (isInitialized) {
        //收到回调 - 初始化完成 - 再次调用一键登录
        _checkAndPreLogin();
      }
    } else {
      //如果已经初始化了，直接调用即可
      _checkAndPreLogin();
    }
  }

  /// 确定初始化完成之后，执行预取号操作
  Future<void> _checkAndPreLogin() async {
    if (_isPreLoginedCompleter.isCompleted) {
      Log.d("已经预取号了，不要重复预取号！");
      return;
    }

    _jverify?.isInitSuccess().then((map) {
      bool result = map[f_result_key];

      if (result) {
        Log.d("初始化已完成了");

        //预取号
        _jverify?.preLogin().then((map) {
          Log.d("预取号接口回调：$map");
          int code = map[f_code_key];
          if (code == 7000) {
            Log.d("预取号码成功");
            _isPreLoginedCompleter.complete(true);
          } else {
            Log.d("预取号码失败");
            _isPreLoginedCompleter.complete(false);
          }
        });
      } else {
        Log.d("初始化JVerify失败了!");
      }
    });
  }

  /// 一键登录（秒验）
  Future<void> loginWithJVerify(TokenCallback callback) async {
    SmartDialog.showLoading();
    bool isPreLogined = await _isPreLoginedCompleter.future;
    SmartDialog.dismiss(status: SmartStatus.loading);

    if (isPreLogined) {
      //如果已经取到号
      mTokenCallback = callback;

      if (_jverify == null) {
        await _initJVerify();

        bool isInitialized = await _initCompleter.future;
        if (isInitialized) {
          //收到回调 - 初始化完成 - 再次调用一键登录
          _checkAndLogin();
        }
      } else {
        //如果已经初始化了，直接调用即可
        _checkAndLogin();
      }
    } else {
      SmartDialog.showNotify(msg: "预取号失败，请检查网络或SIM卡", notifyType: NotifyType.error);
    }
  }

  /// 确定初始化完成之后，执行一键登录
  Future<void> _checkAndLogin() async {
    //已经初始化之后，校验是否初始化完成
    Map<dynamic, dynamic>? map = await _jverify?.isInitSuccess();
    //是否已经初始化完成？
    bool result = map?[f_result_key];

    if (result) {
      Log.d("初始化已完成了");

      //判断当前网络环境是否可以发起认证
      Map<dynamic, dynamic>? map = await _jverify?.checkVerifyEnable();
      bool result = map?[f_result_key];
      if (result) {
        Log.d("当前网络环境支持发起认证");

        _loginAuth();
      } else {
        Log.d("当前网络环境不支持发起认证");
        SmartDialog.showNotify(msg: '当前网络环境不支持一键登录，请检查网络后重试', notifyType: NotifyType.error);
      }
    } else {
      Log.d("初始化JVerify失败了!");
    }
  }

  /// 一检登录的UI样式设置以及执行一键登录
  void _loginAuth() async {
    bool isiOS = Device.isIOS;

    /// 自定义授权的 UI 界面，以下设置的图片必须添加到资源文件里，
    /// android项目将图片存放至drawable文件夹下，可使用图片选择器的文件名,例如：btn_login.xml,入参为"btn_login"。
    /// ios项目存放在 Assets.xcassets。
    JVUIConfig uiConfig = JVUIConfig();
    // uiConfig.authBackgroundImage = "";
    // uiConfig.authBGGifPath = "main_gif";
    // uiConfig.authBGVideoPath="main_vi";
    // uiConfig.authBGVideoPath =
    // "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4";
    // uiConfig.authBGVideoImgPath = "main_v_bg";

    //顶部的TitleBar的设置，背景，文本，颜色，大小，返回图片等配置
    uiConfig.navHidden = false;
    uiConfig.navColor = ColorConstants.appBlue.value;
    uiConfig.navText = "一键登录";
    uiConfig.navTextColor = Colors.white.value;
    uiConfig.navTextBold = true;
    uiConfig.navReturnImgPath = "back"; //图片必须存在

    //Logo的图片展示，大小，位置设置
    uiConfig.logoWidth = 100;
    uiConfig.logoHeight = 100;
    //uiConfig.logoOffsetX = isiOS ? 0 : null;//(screenWidth/2 - uiConfig.logoWidth/2).toInt();
    uiConfig.logoOffsetY = 40;
    uiConfig.logoVerticalLayoutItem = JVIOSLayoutItem.ItemSuper;
    uiConfig.logoHidden = false;
    uiConfig.logoImgPath = "logo"; //图片必须存在

    //电话号码，展示的文本样式控制
    uiConfig.numberFieldWidth = 200;
    uiConfig.numberFieldHeight = 40;
    uiConfig.numFieldOffsetY = isiOS ? 40 : 150;
    uiConfig.numberVerticalLayoutItem = JVIOSLayoutItem.ItemLogo;
    uiConfig.numberColor = Colors.blue.value;
    uiConfig.numberSize = 18;

    //联通/电信提供认证服务，展示的文本样式控制
    uiConfig.sloganOffsetY = isiOS ? 20 : 190;
    uiConfig.sloganVerticalLayoutItem = JVIOSLayoutItem.ItemNumber;
    uiConfig.sloganTextColor = Colors.black.value;
    uiConfig.sloganTextSize = 15;
//        uiConfig.slogan
    //uiConfig.sloganHidden = 0;

    //登录按钮的样式控制，大小，位置，背景，等
    uiConfig.logBtnWidth = 310;
    uiConfig.logBtnHeight = 46;
    uiConfig.logBtnOffsetY = isiOS ? 20 : 260;
    uiConfig.logBtnVerticalLayoutItem = JVIOSLayoutItem.ItemSlogan;
    uiConfig.logBtnText = "本机号码一键登录";
    uiConfig.logBtnTextColor = Colors.white.value;
    uiConfig.logBtnTextSize = 16;
    uiConfig.logBtnTextBold = true;
    uiConfig.logBtnBackgroundPath = "login_btn_normal"; //图片必须存在
    uiConfig.loginBtnNormalImage = "login_btn_normal"; //图片必须存在
    uiConfig.loginBtnPressedImage = "login_btn_normal"; //图片必须存在
    uiConfig.loginBtnUnableImage = "login_btn_normal"; //图片必须存在

    //底部的协议布局，默认勾选，样式，位置等配置
    uiConfig.privacyHintToast = true; //only android 设置隐私条款不选中时点击登录按钮默认显示toast。
    uiConfig.privacyState = isiOS; //设置默认IOS勾选,Android不勾选
    uiConfig.privacyCheckboxSize = 16;
    uiConfig.checkedImgPath = "check_image"; //图片必须存在
    uiConfig.uncheckedImgPath = "uncheck_image"; //图片必须存在
    uiConfig.privacyCheckboxInCenter = true;
    uiConfig.privacyCheckboxHidden = false;
    uiConfig.isAlertPrivacyVc = true;
    uiConfig.privacyOffsetX = 50;
    uiConfig.privacyOffsetY = 50; // 距离底部距离
    uiConfig.privacyVerticalLayoutItem = JVIOSLayoutItem.ItemSuper;
    uiConfig.clauseName = "Room用户协议";
    uiConfig.clauseUrl = ApiConstants.userAgreementUrl;
    uiConfig.clauseBaseColor = Colors.black.value;
    uiConfig.clauseNameTwo = "Room隐私协议";
    uiConfig.clauseUrlTwo = ApiConstants.privacyPolicyUrl;
    uiConfig.clauseColor = Colors.red.value;
    uiConfig.privacyText = ["请阅读并同意", "等协议"];
    uiConfig.privacyTextSize = 13;
    uiConfig.privacyItem = [
      JVPrivacy("Room用户协议", ApiConstants.userAgreementUrl, separator: "*"),
      JVPrivacy("Room隐私协议", ApiConstants.privacyPolicyUrl, separator: "、"),
    ];

    uiConfig.textVerAlignment = 1;
    //uiConfig.privacyWithBookTitleMark = true;
    //uiConfig.privacyTextCenterGravity = false;
    uiConfig.authStatusBarStyle = JVIOSBarStyle.StatusBarStyleLightContent;
    uiConfig.privacyStatusBarStyle = JVIOSBarStyle.StatusBarStyleLightContent;
    uiConfig.modelTransitionStyle = JVIOSUIModalTransitionStyle.CrossDissolve;

    uiConfig.statusBarColorWithNav = true;
    uiConfig.virtualButtonTransparent = true;
    uiConfig.privacyStatusBarColorWithNav = true;
    uiConfig.privacyVirtualButtonTransparent = true;

    //单独页面的进场出场动画
    uiConfig.needStartAnim = true;
    uiConfig.needCloseAnim = true;
    uiConfig.enterAnim = "activity_slide_enter_bottom";
    uiConfig.exitAnim = "activity_slide_exit_bottom";

    //协议页面的标题栏设置
    uiConfig.privacyNavColor = ColorConstants.appBlue.value;
    uiConfig.privacyNavTitleTextColor = Colors.white.value;
    uiConfig.privacyNavTitleTextSize = 18;
    uiConfig.privacyNavTitleTextBold = true;

    uiConfig.privacyNavTitleTitle = "ios only"; //only ios
    uiConfig.privacyNavReturnBtnImage = "back"; //图片必须存在;

    //协议二次弹窗内容设置 -iOS
    uiConfig.agreementAlertViewTitleTexSize = 18;
    uiConfig.agreementAlertViewTitleTextColor = Colors.black.value;
    uiConfig.agreementAlertViewContentTextAlignment = JVTextAlignmentType.center;
    uiConfig.agreementAlertViewContentTextFontSize = 16;
    uiConfig.agreementAlertViewLoginBtnNormalImagePath = "login_btn_normal";
    uiConfig.agreementAlertViewLoginBtnPressedImagePath = "login_btn_normal";
    uiConfig.agreementAlertViewLoginBtnUnableImagePath = "login_btn_normal";
    uiConfig.agreementAlertViewLogBtnTextColor = Colors.white.value;

    //协议二次弹窗内容设置 -Android
    // JVPrivacyCheckDialogConfig privacyCheckDialogConfig = JVPrivacyCheckDialogConfig();
    // // privacyCheckDialogConfig.width = 250;
    // // privacyCheckDialogConfig.height = 100;
    // privacyCheckDialogConfig.offsetX = 0;
    // privacyCheckDialogConfig.offsetY = 0;
    // privacyCheckDialogConfig.titleTextSize = 22;
    // privacyCheckDialogConfig.gravity = "center";
    // privacyCheckDialogConfig.titleTextColor = Colors.black.value;
    // privacyCheckDialogConfig.contentTextGravity = "left";
    // privacyCheckDialogConfig.contentTextSize = 14;
    // privacyCheckDialogConfig.logBtnImgPath = "login_btn_normal";
    // privacyCheckDialogConfig.logBtnTextColor = Colors.black.value;
    // uiConfig.privacyCheckDialogConfig = privacyCheckDialogConfig;

    //弹框模式 （不用，使用的页面模式）
    // JVPopViewConfig popViewConfig = JVPopViewConfig();
    // popViewConfig.width = 280;
    // popViewConfig.height = 420;
    // uiConfig.popViewConfig = popViewConfig;

    /// 调用接口设置 UI
    _jverify?.setCustomAuthorizationView(true, uiConfig, landscapeConfig: uiConfig);

    /// 并发异步的获取 loginToken 与 Token
    final List<Map<dynamic, dynamic>> results = await Future.wait([
      _jverify!.loginAuth(false, timeout: 10000),
      // _jverify!.getToken(timeOut: "10000"),
    ]);

    //第一个必定是LoginToken
    final Map<dynamic, dynamic> loginTokenMap = results[0];
    final loginTokenCode = loginTokenMap['code'];
    final loginTokenMessage = loginTokenMap['message'];
    Log.d("秒验获取LoginToken成功 - loginTokenCode:$loginTokenCode loginTokenMessage:$loginTokenMessage");

    //第二个必定是Token
    // final Map<dynamic, dynamic> tokenMap = results[1];
    // final tokenCode = tokenMap['code'];
    // final tokenMessage = tokenMap['message'];
    // Log.d("秒验获取Token成功 - tokenCode:$tokenCode tokenMessage:$tokenMessage");

    if (loginTokenCode == 6000 /*&& tokenCode == 2000*/) {
      Log.d("两个Token都成功了");
      mTokenCallback?.call("tokenMessage", loginTokenMessage);
      _jverify?.dismissLoginAuthView();
    } else {
      Log.d("两个Token没有全部成功");
      SmartDialog.showToast("获取通信令牌失败。请重试");
    }
  }
}
